/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.cvut.fel.taskpro.view.controller;

import cz.cvut.fel.taskpro.business.isupport.IEnviromentBusiness;
import cz.cvut.fel.taskpro.business.support.BusinessRuleException;
import cz.cvut.fel.taskpro.business.support.TaskProException;
import cz.cvut.fel.taskpro.data.entity.SystemEnviroment;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

/**
 * This controller is responsible for working with enviroment. Controller is
 * view scoped and provide operation as load enviroments, add, edit, import or
 * remove enviroment. Controller is named as enviromentBean.
 *
 * @author Tom
 * @version 1.0.0. beta
 */
@ManagedBean(name = "enviromentBean")
@ViewScoped
public class EnviromentController extends AbstractFileController implements Serializable {

    @Inject
    IEnviromentBusiness enviromentB;
    private List<SystemEnviroment> importedEnviroments;
    private boolean displayPreview;
    private boolean displayCurrEnv;
    private List<SystemEnviroment> loadedEnviroments;
    private List<SystemEnviroment> enviromentToDelete;
    private String description;
    private String value;
    private String key;

    /**
     * This method initialize class. Load all system envrioment and clean out
     * envrioment to delete. Also set up variable to display preview on false
     * and display current selected enviroment to true.
     */
    @PostConstruct
    public void init() {
        displayPreview = false;
        displayCurrEnv = true;
        loadedEnviroments = enviromentB.getAllEnviromentSetting();
        enviromentToDelete = new ArrayList<SystemEnviroment>();
    }

    /**
     * This method load enviroment from uploaded file and preview them to users
     * adding them to inmported enviroment list.
     *
     * @param event event in which is uploaded file
     */
    public void loadEnviroment(FileUploadEvent event) {
        try {
            UploadedFile file = event.getFile();
            InputStream stream;
            stream = event.getFile().getInputstream();
            File enviromentFile = inputStreamToFile(stream, event.getFile().getFileName());
            importedEnviroments = enviromentB.importEnviroment(enviromentFile);
            displayPreview = true;
            displayCurrEnv = false;
            printSuccMessage("Load enviroment: ", "The enviroments from file " + enviromentFile.getName() + " has been successfully loaded.");
        } catch (IOException ex) {
            printErrMessage("File IO", "There was a problem during reading file.");
        } catch (TaskProException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }

    /**
     * This method ask business layer for add all imported enviroments. Then
     * reset imported enviroments list.
     */
    public void addImportedEnviroments() {
        try {
            enviromentB.addEnviroment(importedEnviroments);
            printSuccMessage("Enviroment adding: ", "All enviroments has been successfully added.");
            displayPreview = false;
            displayCurrEnv = true;
            importedEnviroments = null;
            loadedEnviroments = enviromentB.getAllEnviromentSetting();
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }

    /**
     * This method ask business layer for update envrioment. Then ask for remove
     * enviroment to delete and then reset enviromentToDelete list.
     */
    public void modifyEnviroments() {
        try {
            enviromentB.updateEnviroments(loadedEnviroments);
            enviromentB.removeEnviroments(enviromentToDelete);
            loadedEnviroments = enviromentB.getAllEnviromentSetting();
            enviromentToDelete = new ArrayList<SystemEnviroment>();
            printSuccMessage("Enviroment setting save: ", "The enviroment setting has been successfully saved.");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }

    /**
     * This method remove enviroment to remove from actual list, then added it
     * to remove enviroment list. This method does not ask to remove enviroment
     * from database.
     *
     * @param enviromentToRemove enviroment which will be removed from actual
     * enviroment list and this enviroment will be added to enviromentToDelete
     * List.
     */
    public void removeEnv(SystemEnviroment enviromentToRemove) {
        loadedEnviroments.remove(enviromentToRemove);
        enviromentToDelete.add(enviromentToRemove);
    }

    /**
     * This method add enviroment whit specify description, key and value to
     * enviroment list. Then reset all variable.
     */
    public void addEnv() {
        SystemEnviroment enviromentToAdd = new SystemEnviroment();
        enviromentToAdd.setDescription(description);
        enviromentToAdd.setKeyOfSetting(key);
        enviromentToAdd.setValueOfSetting(value);
        loadedEnviroments.add(enviromentToAdd);
        description = null;
        key = null;
        value = null;
    }

    public List<SystemEnviroment> getImportedEnviroments() {
        return importedEnviroments;
    }

    public void setImportedEnviroments(List<SystemEnviroment> importedEnviroments) {
        this.importedEnviroments = importedEnviroments;
    }

    public boolean isDisplayPreview() {
        return displayPreview;
    }

    public void setDisplayPreview(boolean displayPreview) {
        this.displayPreview = displayPreview;
    }

    public List<SystemEnviroment> getLoadedEnviroments() {
        return loadedEnviroments;
    }

    public void setLoadedEnviroments(List<SystemEnviroment> loadedEnviroments) {
        this.loadedEnviroments = loadedEnviroments;
    }

    public boolean isDisplayCurrEnv() {
        return displayCurrEnv;
    }

    public void setDisplayCurrEnv(boolean displayCurrEnv) {
        this.displayCurrEnv = displayCurrEnv;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}
